package org.stayfool.client.util.future;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * Created by stayfool on 2017/2/24.
 */
public abstract class AbstractFuture<V> implements Future<V> {

    private final AtomicBoolean isCancel = new AtomicBoolean(false);
    private CountDownLatch latch = new CountDownLatch(1);
    protected volatile V msg;

    @Override
    public Future<V> sync() throws InterruptedException {
        latch.await();
        return this;
    }

    @Override
    public boolean cancel(boolean mayInterruptIfRunning) {
        isCancel.set(true);
        latch.countDown();
        return true;
    }

    @Override
    public boolean isCancelled() {
        return isCancel.get();
    }

    @Override
    public boolean isDone() {
        return msg != null;
    }

    @Override
    public V get() throws InterruptedException, ExecutionException {
        return msg;
    }

    @Override
    public V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
        latch.await(timeout, unit);
        return msg;
    }

    @Override
    public void setDone(V v) {
        this.msg = v;
        latch.countDown();
    }
}
